package org.codefinger.dao.impl.sql.ast;

import org.codefinger.dao.impl.SQLVisitor;
import org.codefinger.dao.impl.sql.Expression;
import org.codefinger.dao.util.Lang;

public class FunctionExpression implements Expression {

	private String			preffix;

	private Expression[]	params;

	public FunctionExpression(String fnName, Expression[] params) {
		super();
		if (params.length == 0) {
			preffix = Lang.joinStr(fnName.length() + 2, fnName, "()");
			return;
		} else {
			preffix = Lang.joinStr(fnName.length() + 1, fnName, "(");
		}
		this.params = params;
	}

	@Override
	public boolean matchVisit(SQLVisitor visitor) {
		Expression[] params = this.params;
		if (params == null) {
			visitor.appendSQL(preffix);
			return true;
		}
		int sqlSize = visitor.getSqlSize();
		int paramSize = visitor.getParamSize();
		visitor.appendSQL(preffix);
		int length = params.length;
		if (length == 1) {
			if (params[0].matchVisit(visitor)) {
				visitor.appendSQL(')');
				return true;
			}
			visitor.back(sqlSize, paramSize);
			return false;
		}
		if (params[0].matchVisit(visitor)) {
			for (int i = 1; i < length; i++) {
				visitor.appendSQL(',');
				if (params[i].matchVisit(visitor)) {
					continue;
				}
				visitor.back(sqlSize, paramSize);
				return false;
			}
			visitor.appendSQL(')');
			return true;
		}
		return false;
	}

	@Override
	public void visit(SQLVisitor visitor) {
		Expression[] params = this.params;
		if (params == null) {
			visitor.appendSQL(preffix);
			return;
		}
		visitor.appendSQL(preffix);
		int length = params.length;
		if (length == 1) {
			params[0].visit(visitor);
			visitor.appendSQL(')');
			return;
		}
		params[0].visit(visitor);
		for (int i = 1; i < length; i++) {
			visitor.appendSQL(',');
			params[i].visit(visitor);
		}
		visitor.appendSQL(')');
	}
	
}
